<!--------------------------------
 - @Author: Your Name
 - @LastEditor: Your Name
 - @LastEditTime: 2025-11-07
 - Copyright © 2025 Your Name
 --------------------------------->

<template>
  <CommonPage>
    <NTabs v-model:value="activeTab" type="line" animated>
      <NTabPane name="logs" tab="操作日志">
        <MeCrud
          ref="$table"
          v-model:query-items="logQueryItems"
          :scroll-x="1600"
          :columns="logColumns"
          :get-data="api.read"
        >
          <MeQueryItem label="用户名" :label-width="70">
            <n-input
              v-model:value="logQueryItems.username"
              type="text"
              placeholder="请输入用户名"
              clearable
            />
          </MeQueryItem>

          <MeQueryItem label="操作类型" :label-width="70">
            <n-select
              v-model:value="logQueryItems.operation"
              :options="operationOptions"
              label-field="name"
              value-field="value"
              clearable
              placeholder="请选择操作类型"
              filterable
            />
          </MeQueryItem>

          <MeQueryItem label="模块" :label-width="70">
            <n-select
              v-model:value="logQueryItems.module"
              :options="moduleOptions"
              label-field="name"
              value-field="value"
              clearable
              placeholder="请选择模块"
              filterable
            />
          </MeQueryItem>

          <MeQueryItem label="IP地址" :label-width="70">
            <n-input
              v-model:value="logQueryItems.ip"
              type="text"
              placeholder="请输入IP地址"
              clearable
            />
          </MeQueryItem>

          <MeQueryItem label="时间范围" :label-width="70">
            <NDatePicker
              v-model:value="logTimeRange"
              type="datetimerange"
              clearable
              format="yyyy-MM-dd HH:mm:ss"
              @update:value="handleTimeRangeChange"
            />
          </MeQueryItem>

          <template #action>
            <NButton type="primary" @click="handleExportLogs">
              <i class="i-carbon:download mr-4 text-18" />
              导出日志
            </NButton>
          </template>
        </MeCrud>
      </NTabPane>

      <NTabPane name="security-events" tab="安全事件">
        <MeCrud
          ref="$securityEventTable"
          :scroll-x="1200"
          :columns="securityEventColumns"
          :get-data="api.getSecurityEvents"
          :show-query-bar="false"
        />
      </NTabPane>

      <NTabPane name="alert-rules" tab="告警规则">
        <template #action>
          <NButton type="primary" @click="handleAddAlertRule">
            <i class="i-material-symbols:add mr-4 text-18" />
            添加告警规则
          </NButton>
        </template>

        <MeCrud
          ref="$alertRuleTable"
          :scroll-x="1000"
          :columns="alertRuleColumns"
          :get-data="api.getAlertRules"
          :show-query-bar="false"
        />
      </NTabPane>
    </NTabs>

    <MeModal ref="alertRuleModalRef" width="600px">
      <n-form
        ref="alertRuleFormRef"
        label-placement="left"
        label-align="left"
        :label-width="100"
        :model="alertRuleForm"
      >
        <n-form-item
          label="规则名称"
          path="name"
          :rule="{
            required: true,
            message: '请输入规则名称',
            trigger: ['input', 'blur'],
          }"
        >
          <n-input v-model:value="alertRuleForm.name" placeholder="请输入规则名称" />
        </n-form-item>

        <n-form-item label="描述" path="description">
          <n-input
            v-model:value="alertRuleForm.description"
            type="textarea"
            :autosize="{ minRows: 3, maxRows: 5 }"
            placeholder="请输入规则描述"
          />
        </n-form-item>

        <n-form-item
          label="告警条件"
          path="condition"
          :rule="{
            required: true,
            message: '请输入告警条件',
            trigger: ['input', 'blur'],
          }"
        >
          <n-input
            v-model:value="alertRuleForm.condition"
            type="textarea"
            :autosize="{ minRows: 4, maxRows: 6 }"
            placeholder="请输入告警条件，如：登录失败次数>5"
          />
        </n-form-item>

        <n-form-item
          label="严重程度"
          path="severity"
          :rule="{
            required: true,
            message: '请选择严重程度',
            trigger: ['change'],
          }"
        >
          <n-select
            v-model:value="alertRuleForm.severity"
            :options="severityOptions"
            label-field="name"
            value-field="value"
            placeholder="请选择严重程度"
          />
        </n-form-item>

        <n-form-item label="通知渠道" path="notifyChannels">
          <n-select
            v-model:value="alertRuleForm.notifyChannels"
            :options="[
              { label: '邮件', value: 'EMAIL' },
              { label: '短信', value: 'SMS' },
              { label: '企业微信', value: 'WECHAT_WORK' },
              { label: '钉钉', value: 'DINGTALK' },
            ]"
            multiple
            placeholder="请选择通知渠道"
          />
        </n-form-item>

        <n-form-item label="是否启用" path="enabled">
          <NSwitch v-model:value="alertRuleForm.enabled">
            <template #checked>
              启用
            </template>
            <template #unchecked>
              禁用
            </template>
          </NSwitch>
        </n-form-item>
      </n-form>
    </MeModal>
  </CommonPage>
</template>

<script setup>
import { NButton, NDatePicker, NSwitch, NTabPane, NTabs, NTag } from 'naive-ui'
import { MeCrud, MeModal, MeQueryItem } from '@/components'
import { formatDateTime } from '@/utils'
import api from './api'

defineOptions({ name: 'AuditLogMgt' })

const activeTab = ref('logs')

// 操作日志相关
const $table = ref(null)
const logQueryItems = ref({})
const logTimeRange = ref(null)

// 安全事件相关
const $securityEventTable = ref(null)

// 告警规则相关
const $alertRuleTable = ref(null)

// 操作类型选项
const operationOptions = ref([])
api.getOperationOptions().then(({ data = [] }) => (operationOptions.value = data))

// 模块选项
const moduleOptions = ref([])
api.getModuleOptions().then(({ data = [] }) => (moduleOptions.value = data))

// 严重程度选项
const severityOptions = ref([])
api.getSeverityOptions().then(({ data = [] }) => (severityOptions.value = data))

onMounted(() => {
  $table.value?.handleSearch()
})

// 处理时间范围变化
function handleTimeRangeChange(value) {
  if (value && value.length === 2) {
    logQueryItems.value.startTime = new Date(value[0]).toISOString()
    logQueryItems.value.endTime = new Date(value[1]).toISOString()
  }
  else {
    delete logQueryItems.value.startTime
    delete logQueryItems.value.endTime
  }
}

// 导出日志
async function handleExportLogs() {
  try {
    const result = await api.exportLogs(logQueryItems.value)
    $message.success(`日志导出成功: ${result.data.message}`)
    console.log('导出结果:', result.data)
  }
  catch (error) {
    $message.error(`导出失败: ${error.message}`)
    console.error('导出失败:', error)
  }
}

// 告警规则模态框相关
const alertRuleModalRef = ref(null)
const alertRuleFormRef = ref(null)
const alertRuleForm = ref({
  name: '',
  description: '',
  condition: '',
  severity: 'MEDIUM',
  notifyChannels: [],
  enabled: true,
})

// 添加告警规则
function handleAddAlertRule() {
  alertRuleForm.value = {
    name: '',
    description: '',
    condition: '',
    severity: 'MEDIUM',
    notifyChannels: [],
    enabled: true,
  }
  alertRuleModalRef.value?.open({
    title: '添加告警规则',
    onOk: handleSaveAlertRule,
  })
}

// 保存告警规则
async function handleSaveAlertRule() {
  try {
    await alertRuleFormRef.value?.validate()

    const formData = {
      ...alertRuleForm.value,
      createdBy: 1, // 模拟当前用户ID
      updatedBy: 1,
    }

    if (alertRuleForm.value.id) {
      // 更新规则
      await api.updateAlertRule(formData)
      $message.success('告警规则更新成功')
    }
    else {
      // 创建规则
      await api.createAlertRule(formData)
      $message.success('告警规则创建成功')
    }

    alertRuleModalRef.value?.close()
    $alertRuleTable.value?.handleSearch()
  }
  catch (error) {
    $message.error(error.message || '操作失败')
    console.error('操作失败:', error)
  }
}

// 编辑告警规则
function handleEditAlertRule(row) {
  alertRuleForm.value = { ...row }
  alertRuleModalRef.value?.open({
    title: '编辑告警规则',
    onOk: handleSaveAlertRule,
  })
}

// 删除告警规则
function handleDeleteAlertRule(id) {
  const d = $dialog.warning({
    content: '确定删除该告警规则？',
    title: '提示',
    positiveText: '确定',
    negativeText: '取消',
    async onPositiveClick() {
      try {
        d.loading = true
        await api.deleteAlertRule(id)
        $message.success('删除成功')
        d.loading = false
        $alertRuleTable.value?.handleSearch()
      }
      catch (error) {
        console.error(error)
        d.loading = false
        $message.error(error.message || '删除失败')
      }
    },
  })
}

// 操作日志列配置
const logColumns = [
  { title: '用户名', key: 'username', width: 120, ellipsis: { tooltip: true } },
  {
    title: '操作类型',
    key: 'operation',
    width: 150,
    ellipsis: { tooltip: true },
  },
  {
    title: '模块',
    key: 'module',
    width: 120,
    ellipsis: { tooltip: true },
  },
  {
    title: 'URL',
    key: 'url',
    width: 200,
    ellipsis: { tooltip: true },
  },
  {
    title: 'IP地址',
    key: 'ip',
    width: 150,
    ellipsis: { tooltip: true },
  },
  {
    title: '用户代理',
    key: 'userAgent',
    width: 200,
    ellipsis: { tooltip: true },
  },
  {
    title: '执行时间(ms)',
    key: 'executionTime',
    width: 120,
    render: row => h('span', `${row.executionTime}ms`),
  },
  {
    title: '操作状态',
    key: 'status',
    width: 100,
    render: (row) => {
      const statusMap = {
        SUCCESS: { text: '成功', type: 'success' },
        FAILED: { text: '失败', type: 'error' },
      }
      const status = statusMap[row.status] || { text: '未知', type: 'default' }
      return h(NTag, { type: status.type }, { default: () => status.text })
    },
  },
  {
    title: '操作时间',
    key: 'operationTime',
    width: 180,
    render(row) {
      return h('span', formatDateTime(new Date(row.operationTime)))
    },
  },
  {
    title: '操作',
    key: 'actions',
    width: 150,
    align: 'right',
    fixed: 'right',
    hideInExcel: true,
    render(row) {
      return [
        h(
          NButton,
          {
            size: 'small',
            type: 'primary',
            secondary: true,
            onClick: () => handleViewLogDetails(row),
          },
          {
            default: () => '详情',
            icon: () => h('i', { class: 'i-carbon:document-view text-14' }),
          },
        ),
      ]
    },
  },
]

// 安全事件列配置
const securityEventColumns = [
  { title: '事件类型', key: 'eventType', width: 150, ellipsis: { tooltip: true } },
  {
    title: '严重程度',
    key: 'severity',
    width: 120,
    render: (row) => {
      const severityMap = {
        LOW: { text: '低', type: 'info' },
        MEDIUM: { text: '中', type: 'warning' },
        HIGH: { text: '高', type: 'error' },
        CRITICAL: { text: '紧急', type: 'error' },
      }
      const severity = severityMap[row.severity] || { text: '未知', type: 'default' }
      return h(NTag, { type: severity.type }, { default: () => severity.text })
    },
  },
  {
    title: '源IP',
    key: 'sourceIp',
    width: 150,
    ellipsis: { tooltip: true },
  },
  {
    title: '描述',
    key: 'description',
    width: 300,
    ellipsis: { tooltip: true },
  },
  {
    title: '是否已处理',
    key: 'handled',
    width: 120,
    render: (row) => {
      return h(NTag, { type: row.handled ? 'success' : 'warning' }, { default: () => row.handled ? '已处理' : '未处理' })
    },
  },
  {
    title: '创建时间',
    key: 'createdAt',
    width: 180,
    render(row) {
      return h('span', formatDateTime(new Date(row.createdAt)))
    },
  },
  {
    title: '操作',
    key: 'actions',
    width: 200,
    align: 'right',
    fixed: 'right',
    hideInExcel: true,
    render(row) {
      return [
        h(
          NButton,
          {
            size: 'small',
            type: 'primary',
            secondary: true,
            class: 'ml-12px',
            onClick: () => handleViewEventDetails(row),
          },
          {
            default: () => '详情',
            icon: () => h('i', { class: 'i-carbon:document-view text-14' }),
          },
        ),
        !row.handled
          ? h(
              NButton,
              {
                size: 'small',
                type: 'primary',
                class: 'ml-12px',
                onClick: () => handleMarkAsHandled(row),
              },
              {
                default: () => '标记为已处理',
                icon: () => h('i', { class: 'i-carbon:checkmark text-14' }),
              },
            )
          : null,
      ].filter(Boolean)
    },
  },
]

// 告警规则列配置
const alertRuleColumns = [
  { title: '规则名称', key: 'name', width: 200, ellipsis: { tooltip: true } },
  {
    title: '描述',
    key: 'description',
    width: 250,
    ellipsis: { tooltip: true },
  },
  {
    title: '告警条件',
    key: 'condition',
    width: 200,
    ellipsis: { tooltip: true },
  },
  {
    title: '严重程度',
    key: 'severity',
    width: 120,
    render: (row) => {
      const severityMap = {
        LOW: { text: '低', type: 'info' },
        MEDIUM: { text: '中', type: 'warning' },
        HIGH: { text: '高', type: 'error' },
        CRITICAL: { text: '紧急', type: 'error' },
      }
      const severity = severityMap[row.severity] || { text: '未知', type: 'default' }
      return h(NTag, { type: severity.type }, { default: () => severity.text })
    },
  },
  {
    title: '通知渠道',
    key: 'notifyChannels',
    width: 150,
    render: (row) => {
      if (row.notifyChannels && row.notifyChannels.length > 0) {
        return row.notifyChannels.map((channel, index) => {
          const channelMap = {
            EMAIL: '邮件',
            SMS: '短信',
            WECHAT_WORK: '企业微信',
            DINGTALK: '钉钉',
          }
          return h(
            NTag,
            {
              type: 'success',
              style: index > 0 ? 'margin-left: 4px;' : '',
            },
            { default: () => channelMap[channel] || channel },
          )
        })
      }
      return '无'
    },
  },
  {
    title: '状态',
    key: 'enabled',
    width: 100,
    render: row =>
      h(
        NSwitch,
        {
          size: 'small',
          rubberBand: false,
          value: row.enabled,
          onUpdateValue: value => handleToggleRuleStatus(row, value),
        },
        {
          checked: () => '启用',
          unchecked: () => '禁用',
        },
      ),
  },
  {
    title: '创建时间',
    key: 'createdAt',
    width: 180,
    render(row) {
      return h('span', formatDateTime(new Date(row.createdAt)))
    },
  },
  {
    title: '操作',
    key: 'actions',
    width: 200,
    align: 'right',
    fixed: 'right',
    hideInExcel: true,
    render(row) {
      return [
        h(
          NButton,
          {
            size: 'small',
            type: 'primary',
            secondary: true,
            class: 'ml-12px',
            onClick: () => handleEditAlertRule(row),
          },
          {
            default: () => '编辑',
            icon: () => h('i', { class: 'i-material-symbols:edit-outline text-14' }),
          },
        ),
        h(
          NButton,
          {
            size: 'small',
            type: 'error',
            style: 'margin-left: 12px;',
            onClick: () => handleDeleteAlertRule(row.id),
          },
          {
            default: () => '删除',
            icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
          },
        ),
      ]
    },
  },
]

// 查看日志详情
function handleViewLogDetails(row) {
  $message.info(`查看日志详情: ${row.id}`)
  // 实际项目中这里会打开详情模态框
  console.log('日志详情:', row)
}

// 查看事件详情
function handleViewEventDetails(row) {
  $message.info(`查看事件详情: ${row.id}`)
  // 实际项目中这里会打开详情模态框
  console.log('事件详情:', row)
}

// 标记为已处理
function handleMarkAsHandled(row) {
  $message.info(`标记事件为已处理: ${row.id}`)
  // 实际项目中这里会调用API更新事件状态
  console.log('标记为已处理:', row)
}

// 切换规则状态
async function handleToggleRuleStatus(row, value) {
  try {
    await api.updateAlertRule({ id: row.id, enabled: value })
    $message.success('状态更新成功')
    $alertRuleTable.value?.handleSearch()
  }
  catch (error) {
    $message.error(error.message || '状态更新失败')
    console.error('状态更新失败:', error)
  }
}
</script>
